package com.laizhenghua.share.device.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.laizhenghua.share.common.core.domain.R;
import com.laizhenghua.share.device.domain.entity.Cabinet;
import com.laizhenghua.share.device.domain.entity.Station;
import com.laizhenghua.share.device.domain.entity.StationLocation;
import com.laizhenghua.share.device.mapper.StationMapper;
import com.laizhenghua.share.device.repository.StationLocationRepository;
import com.laizhenghua.share.device.service.ICabinetService;
import com.laizhenghua.share.device.service.IRegionService;
import com.laizhenghua.share.device.service.IStationService;
import com.laizhenghua.share.system.api.model.LoginUser;
import com.share.common.security.utils.SecurityUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.stereotype.Service;

import java.io.ObjectInputStream;
import java.util.Date;
import java.util.List;

/**
 * TODO
 *
 * @Description
 * @Author laizh
 * @Date 2025/7/19 16:37
 **/
@Service
public class IStationServiceImpl extends ServiceImpl<StationMapper, Station> implements IStationService {
    private final Logger log = LoggerFactory.getLogger(IStationServiceImpl.class);
    private final ICabinetService iCabinetService;
    private final IRegionService iRegionService;
    private final StationLocationRepository stationLocationRepository;

    @Autowired
    public  IStationServiceImpl(
            ICabinetService iCabinetService,
            IRegionService iRegionService,
            StationLocationRepository stationLocationRepository) {
        this.iCabinetService = iCabinetService;
        this.iRegionService = iRegionService;
        this.stationLocationRepository = stationLocationRepository;
    }

    @Override
    public List<Station> searchPageList(Station station) {
        List<Station> stations = baseMapper.searchPageList(station);
        for (Station s : stations) {
            Long cabinetId = s.getCabinetId(); // 柜机id
            Cabinet cabinet = iCabinetService.getById(cabinetId);
            if (ObjectUtil.isNotNull(cabinet)) {
                String cabinetNo = cabinet.getCabinetNo();
                s.setCabinetNo(cabinetNo);
            } else {
                log.error("---> Cabinet[id={}] is null", cabinetId);
            }
        }
        return stations;
    }

    @Override
    public Station customSave(Station station) {
        LoginUser user = SecurityUtils.getLoginUser();
        if (ObjectUtil.isNull(station.getCreateBy())) {
            if (ObjectUtil.isNotNull(user)) {
                station.setCreateBy(user.getUsername());
            }
            station.setCreateTime(new Date());
        }
        if (ObjectUtil.isNotNull(station.getId())) {
            if (ObjectUtil.isNotNull(user)) {
                station.setUpdateBy(user.getUsername());
            }
            station.setUpdateTime(new Date());
        }
        // 查询行政区划信息
        R<String> provinceName = iRegionService.getNameByCode(station.getProvinceCode());
        R<String> cityName = iRegionService.getNameByCode(station.getCityCode());
        R<String> DistrictName = iRegionService.getNameByCode(station.getDistrictCode());
        StringBuilder sb = new StringBuilder();
        if (ObjectUtil.isNotNull(provinceName.getData())) {
            sb.append(provinceName.getData()); // 省
        }
        if (ObjectUtil.isNotNull(cityName.getData())) {
            sb.append(cityName.getData()); // 市
        }
        if (ObjectUtil.isNotNull(DistrictName.getData())) {
            sb.append(DistrictName.getData()); // 区
        }
        String fullAddress = StrUtil.format("{}{}", sb.toString(), station.getAddress());
        station.setFullAddress(fullAddress);
        // 站点位置信息存储
        boolean isUpdate = ObjectUtil.isNotNull(station.getId());
        boolean b = this.saveOrUpdate(station);
        if (b) {
            if (isUpdate) {
                updateStationLocation(station.getId(), station.getLongitude().doubleValue(), station.getLatitude().doubleValue());
            } else {
                saveStationLocation(station.getId(), station.getLongitude().doubleValue(), station.getLatitude().doubleValue());
            }
            return this.getById(station.getId());
        }
        return null;
    }

    @Override
    public String updateStationLocation() {
        List<Station> list = this.list();
        for (Station station : list) {
            StationLocation stationLocation = stationLocationRepository.getByStationId(station.getId());
            if (ObjectUtil.isNotNull(stationLocation)) {
                continue;
            }
            stationLocation = new StationLocation();
            stationLocation.setId(ObjectId.get().toString());
            stationLocation.setStationId(station.getId());
            stationLocation.setLocation(new GeoJsonPoint(station.getLongitude().doubleValue(), station.getLatitude().doubleValue()));
            stationLocation.setCreateTime(new Date());
            stationLocationRepository.save(stationLocation);
        }
        return "更新完成";
    }

    private void saveStationLocation(Long stationId, double x, double y) {
        StationLocation stationLocation = new StationLocation();
        stationLocation.setId(ObjectId.get().toString());
        stationLocation.setStationId(stationId);
        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(x, y);
        stationLocation.setLocation(geoJsonPoint);
        stationLocation.setCreateTime(new Date());
        stationLocationRepository.save(stationLocation);
    }

    private void updateStationLocation(Long stationId, double x, double y) {
        StationLocation stationLocation = stationLocationRepository.getByStationId(stationId);
        GeoJsonPoint geoJsonPoint = new GeoJsonPoint(x, y);
        stationLocation.setLocation(geoJsonPoint);
        stationLocationRepository.save(stationLocation);
    }
}
